/*
	This file is part of PropExtractor.

	PropExtractor is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	PropExtractor is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with PropExtractor. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _PEMODEL_H_
#define _PEMODEL_H_

namespace pe
{

	struct PEStream;

	struct PEVertexBuffer
	{
		float* position;
		unsigned int element_size;
		unsigned int total;
	};

	struct PETexCoordBuffer
	{
		float* uv;
		unsigned int total;
	};

	struct PENormalBuffer
	{
		float* normal;
		unsigned int total;
	};

	struct PEIndexBuffer
	{
		unsigned int* index;
		unsigned int element_size;
		unsigned int total;
	};

	struct PEMaterialRaw
	{
		wchar_t* name;

		wchar_t* texture_diffuse;
		wchar_t* texture_specular;
		unsigned int texture_total;

		PEMaterialRaw* submaterial;
		unsigned int submaterial_total;
	};

	struct PEBoneRaw
	{
		wchar_t* name;

		bool localtransform;
		glm::detail::tmat4x4<float> inv_bind_matrix;
		glm::detail::tvec3<float> inv_bind_position;

		PEBoneRaw* parent;		
		PEBoneRaw** children;
		unsigned int children_filled;
		unsigned int children_total;
	};

	struct PESkinWeightRaw
	{
		PEBoneRaw* bone;
		unsigned int bone_id;
		unsigned int vertex_id;
		float weight;
	};

	struct PESkinRaw
	{
		PESkinWeightRaw* skinweight;
		unsigned int skinweight_total;
	};

	struct PEMeshRaw
	{
		wchar_t* name;

		PEVertexBuffer* vertices;
		PENormalBuffer* normals;
		PETexCoordBuffer* texcoords;

		PEIndexBuffer* vertex_indices;
		PEIndexBuffer* texcoord_indices;
		PEIndexBuffer* normal_indices;

		PEMaterialRaw* material;

		PEBoneRaw** bonesused;
		unsigned int bonesused_total;

		PESkinRaw* skinboneweights;
		unsigned int skinboneweights_total;
	};

	struct PEModelRaw
	{
		wchar_t* name;

		PEStream* handle;

		PEMeshRaw* mesh;
		unsigned int mesh_total;

		PEMaterialRaw* material;
		unsigned int material_total;

		PEBoneRaw* bone;
		unsigned int bone_total;
	};

	PE_EXPORT int PEMaterialRawInit(PEMaterialRaw* a_Material);
	PE_EXPORT int PEBoneRawInit(PEBoneRaw* a_Bone);
	PE_EXPORT int PESkinBoneWeightsRawInit(PESkinRaw* a_SkinWeight);
	PE_EXPORT int PEMeshRawInit(PEMeshRaw* a_Mesh);
	PE_EXPORT int PEModelRawInit(PEModelRaw* a_Model);

	PE_EXPORT int PEMaterialRawDelete(PEMaterialRaw* a_Material);
	PE_EXPORT int PEMeshRawDelete(PEMeshRaw* a_Mesh);
	PE_EXPORT int PEModelRawDelete(PEModelRaw* a_Model);

	PE_EXPORT int PEModelRawSaveToObj(PEModelRaw* a_Model, const wchar_t* a_FilePath);
	PE_EXPORT int PEModelRawSaveToCollada(PEModelRaw* a_Model, const wchar_t* a_FilePath);
	PE_EXPORT int PEModelRawSaveToFile(PEModelRaw* a_Model, const wchar_t* a_FilePath);

}; // namespace pe

#endif